<template>
  <div class="t-progress-bar" :class="classes">
    <div class="progress-bit" :style="styles"></div>
  </div>
</template>
<script>
export default {
  name: "TProgressBar",
  props: {
    background: String,
    on: {
      type: Boolean,
      default: false
    },
    infinite: {
      type: Boolean,
      default: false
    },
    delay: {
      type: Number
    },
    worked: {
      type: Number || undefined,
      default: undefined
    },
    total: {
      type: Number,
      default: 100
    },
    show: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      c_on: false,
      c_show: this.show,
      on_token: 0,
      show_token: 0
    };
  },
  watch: {
    on(v) {
      if (v)
        this.show_token = window.setTimeout(() => {
          this.c_on = false;
        }, this.delay);
      else {
        this.show_token && window.clearTimeout(this.show_token);
        this.c_on = true;
      }
    },
    c_on(v) {
      this.$emit("update:on", v);
    },
    show(v) {
      if (v)
        this.on_token = window.setTimeout(() => {
          this.c_show = true;
        }, this.delay);
      else this.on_token && window.clearTimeout(this.on_token);
      this.c_show = false;
    },
    done(v) {
      if (v)
        this.show_token = window.setTimeout(() => {
          this.c_on = false;
        }, this.delay);
      else this.show_token && window.clearTimeout(this.show_token);
      this.c_on = true;
    }
  },
  computed: {
    workedVal() {
      if (!this.c_on) return 0;
      return Math.min(Math.max(1, Number(this.worked)), this.total);
    },
    styles() {
      const style = {};
      if (this.c_show) style.display = "";
      else style.display = "none";
      if (this.background) style.backgroundColor = this.background;
      if (this.infinite) {
        style.width = "10%";
        style.opacity = "1";
      } else {
        style.width = 100 * (this.workedVal / this.total) + "%";
      }
      if (!this.c_on) {
        if (!this.infinite) style.width = "inherit";
        else style.opacity = "0";
      }
      return style;
    },
    classes() {
      const classes = [];
      if (this.c_on) {
        classes.push("active");
      }
      if (this.infinite) classes.push("infinite");
      else classes.push("discrete");
      if (!this.c_on) {
        classes.push("done");
      }
      return classes;
    },
    eleStyles() {
      const style = {};
      return style;
    }
  },
  mounted() {
    if (this.on) {
      this.on_token = window.setTimeout(() => {
        this.c_on = true;
      }, this.delay);
    } else this.c_on = false;
  }
};
</script>
<style>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

.t-progress-bar {
  width: 100%;
  height: 6px;
  overflow: hidden; /* keep progress bit in bounds */
  position: relative;
}

.t-progress-bar .progress-bit {
  width: 2%;
  height: 6px;
  position: absolute;
  left: 0;
  display: none;
  border-radius: 3px;
}

.t-progress-bar.active .progress-bit {
  display: inherit;
}

.t-progress-bar.discrete .progress-bit {
  left: 0;
  transition: width 100ms linear;
}

.t-progress-bar.discrete.done .progress-bit {
  width: 100%;
}

.t-progress-bar.infinite .progress-bit {
  animation-name: progress;
  animation-duration: 4s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  transform: translate3d(0px, 0px, 0px);
}

/**
 * The progress bit has a width: 2% (1/50) of the parent container. The animation moves it from 0% to 100% of
 * that container. Since translateX is relative to the progress bit size, we have to multiple it with
 * its relative size to the parent container:
 *  50%: 50 * 50 = 2500%
 * 100%: 50 * 100 - 50 (do not overflow): 4950%
 */
@keyframes progress {
  from {
    transform: translateX(-100%) scaleX(1);
  }
  50% {
    transform: translateX(450%) scaleX(1);
  }
  to {
    transform: translateX(1000%) scaleX(1);
  }
}
</style>
